import os
import subprocess


"""
    Execute commands in terminal

    Example:
        execute_in_terminal([
                        'cd /home/richard/Projects/Open_Duck_Mini/Open_Duck_Playground', 
                        'uv run playground/open_duck_mini_v2/mujoco_infer.py'
                    ])
"""
def execute_in_terminal(commands: list, echo_each_command: bool = False, keep_terminal_open_on_exit: bool = False) -> subprocess.CompletedProcess:
    assert os.name == 'posix', "This function only supports Linux platform for now."
    
    try:
        inside_terminal_command = ''

        # if any command fails, will be trapped here. But Ctrl+C will be ignored.
        inside_terminal_command += 'trap $\'read -n 1 -s -r -p \\\'User command failed! Press any key to continue...\\\'\' ERR; trap $\'\' SIGINT; '

        # should we echo each user command in terminal?
        if echo_each_command:
            inside_terminal_command += 'PS4=\'\\e[1;32mExecuting Command: \\e[0m\'; set -x; '    # change execute prompt, only for cosmetic

        # ACTUAL user commands
        for idx, command in enumerate(commands):
            if idx != 0:
                inside_terminal_command += ' && '

            inside_terminal_command += command

        # should we keep terminal open on exit?
        if keep_terminal_open_on_exit:
            inside_terminal_command += '; set +x; echo; read -n 1 -s -r -p \'Press any key to continue...\''

        final_command = ''
        final_command += f'unset GTK_PATH; '                 # unset GTK_PATH to avoid gnome-terminal launch error. See: https://github.com/ros2/ros2/issues/1406
        final_command += f'gnome-terminal -- bash -c \"{inside_terminal_command}\"' # execute in terminal

        print(f'execute_in_terminal():\n{final_command}')
        return subprocess.run(final_command, shell=True, check=True, capture_output=True, text=True)
    except subprocess.CalledProcessError as e:
        raise Exception(f"subprocess.CalledProcessError.\nErrorCode: {e.returncode}\nReason: {str(e.stderr)}")
    